package AttachmentService

import (
	"fmt"
	"gdshop-back-end-go/common/request/AttachmentReq"
	"gdshop-back-end-go/common/response"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/util/gconv"
	"strings"
)

func UploadChunk(r *ghttp.Request) *response.JsonResponse {
	var parames *AttachmentReq.UploadChunk
	var err error
	g.TryCatch(func() {
		err = r.Parse(&parames)
	}, func(exception error) {
		if strings.Contains(exception.Error(), "EOF") {
			fmt.Println("UploadChunk 文件断流 错误本体：", exception.Error())
		}
		err = exception
	})
	if err != nil {
		return response.FailByRequestMessage(r, "上传失败："+err.Error())
	}
	//设置内存大小
	err = r.ParseMultipartForm(32 << 20) // 双目运算 32*2^20
	if err != nil {
		return response.FailByRequestMessage(r, "上传失败："+err.Error())
	}
	file := r.GetUploadFile("file")
	if file == nil {
		return response.FailByRequestMessage(r, "文件不能为空")
	}
	ctx := r.GetCtx()
	aModel, err := GetModelByMd5(ctx, parames.FileMd5)
	if err != nil {
		return response.FailByRequestMessage(r, "上传失败："+err.Error())
	}
	if aModel != nil {
		return response.JsonByAll(r, 21001, "文件已存在")
	}
	var oneByte int64 = 1048576 // 1MB
	// 默认允许上传5MB
	allowSizeConfig := g.Cfg().GetInt64("upload.AllowSize", 5)
	allowSize := allowSizeConfig * oneByte
	if file.Size > allowSize {
		return response.FailByRequestMessage(r, "文件大小不能超过"+gconv.String(allowSizeConfig)+"MB")
	}
	uploadChunkPath := g.Cfg().GetString("upload.UploadChunkPath")

	_, err = pieceSave(ctx, uploadChunkPath, parames.PieceMd5, file)
	if err != nil {
		return response.FailByRequestMessage(r, "上传失败："+err.Error())
	}
	// 保存分片信息
	err = chunkAdd(ctx, parames.Index, parames.FileMd5, parames.PieceMd5)
	if err != nil {
		return response.FailByRequestMessage(r, "上传失败："+err.Error())
	}
	// 判断是否上传完成
	isFinish, err := chunkIsFull(ctx, parames.FileMd5, parames.Chunks)
	if err != nil {
		return response.FailByRequestMessage(r, "上传失败："+err.Error())
	}
	if !isFinish {
		return response.SuccessByRequestMessageData(r, "分片上传完成", parames.Index)
	}
	return response.JsonByAll(r, 21004, "全部上传完成")

	/*
		// 判断是否合并中
		isMerge, err := isMerging(ctx, parames.FileMd5)
		if err != nil {
			return response.FailByRequestMessage(r, "上传失败："+err.Error())
		}
		if !isMerge {
			return response.SuccessByRequestMessageData(r, "分片上传完成", parames.Index)
		}
		// 合并文件
		// 在Redis里面加锁
		err = setMerging(ctx, parames.FileMd5)
		if err != nil {
			return response.FailByRequestMessage(r, "上传失败："+err.Error())
		}
		// 合并文件
		saveFilePreFix := g.Cfg().GetString("upload.WwwrootPath")
		url := "/upload/" + gtime.Now().Format("Ym") + "/" + gtime.Now().Format("d") + "/"
		fileExt := gfile.Ext(parames.Filename)
		fileName := grand.Letters(2) + grand.S(30) + fileExt
		newFileMd5, err := mergeFile(ctx, parames.FileMd5, uploadChunkPath, saveFilePreFix+url, fileName, parames.LastModified)
		if err != nil {
			return response.FailByRequestMessage(r, "上传失败："+err.Error())
		}
		// 删除分片信息
		err = chunkDelete(ctx, parames.FileMd5)
		if err != nil {
			return response.FailByRequestMessage(r, "上传失败："+err.Error())
		}
		clearSet(ctx, parames.FileMd5)

		if newFileMd5 != parames.FileMd5 {
			fmt.Println("文件MD5不一致 ", newFileMd5, parames.FileMd5)
			return response.FailByRequestMessage(r, "上传失败：文件MD5不一致")
		}
		// 添加数据到数据库
		insertData := g.Map{
			"original_name": parames.Filename,
			"save_name":     fileName,
			"save_path":     url,
			"url":           url + fileName,
			"extension":     strings.Trim(fileExt, "."),
			"mime":          contentType,
			"size":          parames.FileSize,
			"md5":           parames.FileMd5,
		}
		res := UploadAdd(r, insertData)
		if res.Code != 0 {
			return res
		}
		resData := gconv.Map(res.Data)
		insertData["id"] = resData["id"]
		PhotoPreFix := g.Cfg().GetString("upload.PhotoPreFix")
		insertData["base_url"] = PhotoPreFix
		return response.SuccessByRequestMessageData(nil, "成功", insertData)*/
}
